package com.ywgt.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.ywgt.pojo.*;
import com.ywgt.service.*;
import com.ywgt.util.ResponseUtil;
import com.ywgt.util.WxResponseUtil;
import io.swagger.annotations.ApiModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

@CrossOrigin
@RestController
@RequestMapping("/wx/goods")
@ApiModel("商品页面")
public class GoodsController {

    @Autowired
    GoodsService goodsService;

    @Autowired
    CategoryService categoryService;

    @Autowired
    SearchHistoryService searchHistoryService;

    @Autowired
    GoodsProductService goodsProductService;

    @Autowired
    GoodsSpecificationService goodsSpecificationService;

    @Autowired
    GoodsAttributeService goodsAttributeService;

    @Autowired
    BrandService brandService;

    @Autowired
    CommentService commentService;

    @Autowired
    FootprintService footprintService;

    @Autowired
    UserService userService;

    @Autowired
    IssueService issueService;

    @Autowired
    GrouponRulesService grouponRulesService;

    @Autowired
    CollectService collectService;


    private final static ArrayBlockingQueue<Runnable> QUEUE=new ArrayBlockingQueue<>(9);

    private final static RejectedExecutionHandler HANDLER=new ThreadPoolExecutor.CallerRunsPolicy();

    private static ThreadPoolExecutor executor=new ThreadPoolExecutor(5,10,60, TimeUnit.SECONDS,
            QUEUE,HANDLER);

    @GetMapping("/detail")
    public Object detail(@RequestParam(required = false) Integer userId,@NotNull Integer id){

        Goods good = goodsService.getById(id);

        Map<String,Object> searchMap=new HashMap<>();
        searchMap.put("goods_id",id);
        Callable<List> goodsAttributeCallable=()->goodsAttributeService.listByMap(searchMap);
        Callable<List> goodsProductCallable=()->goodsProductService.listByMap(searchMap);
        Callable<List> goodsSpecificationCallable=()->goodsSpecificationService.getByGoodId(id);
        Callable<List> issueCallable=()->issueService.list();
        Callable<Brand> brandCallable=()->{
           return good.getBrandId()==0?new Brand():brandService.getById(good.getBrandId());
        };
        Callable<Map> commentsCallable=()->{
            List<Comment> comments=commentService.getByGoodsId(id,1,2);
            List<Map<String, Object>> commentsVo = new ArrayList<>(comments.size());
            for (Comment comment : comments) {
                Map<String, Object> c = new HashMap<>();
                c.put("id", comment.getId());
                c.put("addTime", comment.getAddTime());
                c.put("content", comment.getContent());
                User user = userService.getById(comment.getUserId());
                c.put("nickname", user.getNickname());
                c.put("avatar", user.getAvatar());
                c.put("picList", comment.getPicUrls());
                commentsVo.add(c);
            }
            Map<String, Object> commentList = new HashMap<>();
            commentList.put("count", comments.size());
            commentList.put("data", commentsVo);
            return commentList;
        };
        Callable<List> grouponRuleCallable=()->grouponRulesService.getByGoodsId(id);

        int collectCount=0;
        if(userId!=null){
            collectCount=collectService.counts(userId,id);
            Footprint footprint=new Footprint();
            footprint.setGoodsId(id);
            footprint.setUserId(userId);
            footprint.setDeleted(false);
            footprintService.save(footprint);
            goodsService.incrBrowser(id);
        }
        FutureTask<List> goodsAttributeTask=new FutureTask<>(goodsAttributeCallable);
        FutureTask<List> goodsProductTask=new FutureTask<>(goodsProductCallable);
        FutureTask<List> goodsSpecificationTask=new FutureTask<>(goodsSpecificationCallable);
        FutureTask<List> grouponRuleTask=new FutureTask<>(grouponRuleCallable);
        FutureTask<List> issueeTask=new FutureTask<>(issueCallable);
        FutureTask<Brand> brandTask=new FutureTask<>(brandCallable);
        FutureTask<Map> commentsTask=new FutureTask<>(commentsCallable);

        executor.submit(goodsAttributeTask);
        executor.submit(goodsProductTask);
        executor.submit(goodsSpecificationTask);
        executor.submit(grouponRuleTask);
        executor.submit(issueeTask);
        executor.submit(brandTask);
        executor.submit(commentsTask);

        Map<String,Object> data=new HashMap<>();
        try {
            data.put("info", good);
            data.put("userHasCollect", collectCount);
            data.put("issue", issueeTask.get());
            data.put("comment", commentsTask.get());
            data.put("specificationList", goodsSpecificationTask.get());
            data.put("productList", goodsProductTask.get());
            data.put("attribute", goodsAttributeTask.get());
            data.put("brand",brandTask.get());
            data.put("groupon", grouponRuleTask.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 商品分享图片地址
        data.put("shareImage", good.getShareUrl());
        return ResponseUtil.ok(data);
    }

    @GetMapping("/count")
    public Object getCount(){
        LambdaQueryWrapper<Goods> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Goods::getIsOnSale,1);
        int count = goodsService.count(wrapper);
        Map<String,Object> goodsCount=new HashMap<>();
        goodsCount.put("goodsCount",count);
        return WxResponseUtil.ok(goodsCount);
    }

    @GetMapping("/category")
    public Object getCategories(Integer id){
       return categoryService.getCategoriesById(id);
    }

    @GetMapping("/list")
    public Object getGoods(Integer categoryId, Integer brandId, String keyword, Boolean isNew, Boolean isHot,
                           Integer userId, @RequestParam(defaultValue = "1") Integer page,
                           @RequestParam(defaultValue = "10") Integer size,
                           @RequestParam(defaultValue = "sort_order") String sort,
                           @RequestParam(defaultValue = "asc") String order){
        if(userId!=null&&StringUtils.isEmpty(keyword)){
            SearchHistory searchHistory=new SearchHistory();
            searchHistory.setUserId(userId);
            searchHistory.setDeleted(false);
            searchHistory.setKeyword(keyword);
            searchHistory.setFrom("wx");
            searchHistoryService.save(searchHistory);
        }
        Page<Goods> goods= goodsService.getGoodsByCondition(categoryId,brandId,keyword,isHot,isNew,page,size,sort,order);
        List<Integer> ids=goodsService.getCategoryIds(brandId,keyword,isHot,isNew);
        List<Category> categories=new ArrayList<>();
        if(ids.size()>0){
            categories = categoryService.listByIds(ids);
        }
        Map<String,Object> data=new HashMap<>();
        long total = goods.getTotal();
        int pages = goods.getPages();
        List<Goods> items = goods.getResult();
        data.put("goodsList", goods);
        data.put("count", total);
        data.put("filterCategoryList", categories);
        data.put("totalPages", pages);
        return ResponseUtil.ok(data);
    }


}
